package com.example.springboottest.example.zookeeper.listener;

import com.example.springboottest.example.zookeeper.ZKclient;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.cache.*;

import java.io.UnsupportedEncodingException;

/**
 * Tree Cache 可以看作是 Node Cache 和 Path Cache 的合体。Tree Cache 不光能监听子节点，还能监听节点自身。
 */
public class ZkCuratorTreeWatcherDemo {
    private String workerPath = "/test/listener/remoteNode";
    private String subWorkerPath = "/test/listener/remoteNode/id-";

    public static void main(String[] args) {
        new ZkCuratorTreeWatcherDemo().testNodeCache();
    }

    public void testNodeCache() {
        //检查节点是否存在，没有则创建
        boolean isExist = ZKclient.instance.isNodeExist(workerPath);
        if (!isExist) {
            ZKclient.instance.createNode(workerPath, null);
        }
        CuratorFramework client = ZKclient.instance.getClient();
        try {
            /**
             * PathChildrenCache 子节点缓存用于子节点的监听，监控当前节点的子节点被创建、更新或者删除，需要强调：
             * ⚫ 只能监听子节点，监听不到当前节点。
             * ⚫ 不能递归监听，子节点下的子节点不能递归监控。
             */
            TreeCache treeCache = new TreeCache(client, workerPath);
            TreeCacheListener listener = new TreeCacheListener() {
                @Override
                public void childEvent(CuratorFramework client,
                                       TreeCacheEvent event) {
                    try {
                        ChildData data = event.getData();
                        if (data == null) {
                            System.out.println("数据为空");
                            return;
                        }
                        switch (event.getType()) {
                            case NODE_ADDED:
                                System.out.println("[TreeCache]节点增加, path=" + data.getPath() + ", data="
                                        + new String(data.getData(), "UTF-8"));
                                break;
                            case NODE_UPDATED:
                                System.out.println("[TreeCache]节点更新, path=" + data.getPath() + " data=" +
                                        new String(data.getData(), "UTF-8"));
                                break;
                            case NODE_REMOVED:
                                System.out.println("[TreeCache]节点删除, path=" + data.getPath() + " data=" +
                                        new String(data.getData(), "UTF-8"));
                                break;
                            default:
                                break;
                        }
                    } catch (
                            UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }
                }
            };
            //设置监听器
            treeCache.getListenable().addListener(listener);
            //启动缓存视图
            treeCache.start();
            //创建 3 个子节点
            //增加节点需要通过ZKclient.instance.createNode 创建才能感知
            //通过客户端  create不能感知到
            for (int i = 0; i < 3; i++) {
                ZKclient.instance.createNode(subWorkerPath + i, null);
            }
            // 第 1 次变更节点数据
//            client.setData().forPath(workerPath, "第 1 次更改内容".getBytes());
//            Thread.sleep(1000);
//            // 第 2 次变更节点数据
//            client.setData().forPath(workerPath, "第 2 次更改内容".getBytes());
//            Thread.sleep(1000);
//            // 第 3 次变更节点数据
//            client.setData().forPath(workerPath, "第 3 次更改内容".getBytes());
//            Thread.sleep(1000);
//            // 第 4 次变更节点数据
//            client.delete().forPath(workerPath);
            Thread.sleep(Integer.MAX_VALUE);
        } catch (Exception e) {
            System.out.println("创建 NodeCache 监听失败, path=" + workerPath);
        }
    }
}
